<?php

namespace Xrfg\Api\Trading\Spot\Resources;

use App\Http\Resources\Resource;
use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Facades\Redis;
use PDOException;
use Xrfg\Core\Trading\Spot\Models\Kline;
use Xrfg\Core\Trading\Spot\Models\Pair;

class RecommendSymbolResource extends Resource
{
    public function toArray($request)
    {
        // 行情
        list($open, $close, $high, $low, $number, $total) = $this->getTicker();
        // K线
        if (in_array($this->symbol, array_keys(config('huobi')))) {
            $time = '1day';
            $kline = self::huobiKline($this->symbol, $time, 30);
            if (!$kline) {
                $kline = [];
            }
        } else {
            $klines = Cache::remember(
                sprintf('res:recommend:kline:%s', $this->symbol),
                now()->addSecond(),
                function () {
                    $type = 86400000 / 60000;
                    try {
                        $kline = (new Kline($this->symbol, $type))
                            ->orderBy('time_open', 'desc')
                            ->limit(30)
                            ->get();

                        return $kline;
                    } catch (PDOException $exception) {
                        return collect();
                    }
                }
            );
            $kline = [];
            foreach ($klines as $item) {
                $kline[] = [
                    'time' => $item->time_open,
                    'open' =>  $item->price_open,
                    'close' =>  $item->price_close,
                    'high' =>  $item->price_high,
                    'low' =>  $item->price_low,
                    'volume' =>  $item->trades_number,
                    'trades_total' =>  $item->trades_total,
                    'trades_count' =>  $item->trades_count,
                ];
            }
        }


        /* @var Pair $this */
        return [
            'id' => $this->id,
            'symbol' => $this->symbol,
            'status' => $this->status,
            'coin_name' => $this->coin_name,
            'coin_id' => $this->coin_id,
            'coin_decimals' => $this->coin_decimals,
            'market_name' => $this->market_name,
            'market_id' => $this->market_id,
            'market_decimals' => $this->market_decimals,
            'price_step' => $this->price_step,
            'number_min' => $this->number_min,
            'number_step' => $this->number_step,
            'total_min' => $this->total_min,
            'open' => $open,
            'close' => $close,
            'high' => $high,
            'low' => $low,
            'number' => $number,
            'total' => $total,
            'kline' => $kline
        ];
    }

    private function getTicker()
    {
        /** @var Pair $this */
        $symbol = $this->symbol;
        $redis = Redis::connection();

        if (in_array($symbol, array_keys(config('huobi')))) {
            $symbol = strtolower(str_replace('/', '', $symbol));
            $ticker = $redis->get('huobi:ticker:'.$symbol);
        } else {
            $ticker = $redis->get('etf:ticker:'.$symbol);
        }

        if (!$ticker) {
            return [
                '0.00000000',
                '0.00000000',
                '0.00000000',
                '0.00000000',
                '0.00000000',
                '0.00000000',
            ];
        } else {
            $ticker = json_decode($ticker, true);

            return [
                $ticker['open'],
                $ticker['close'],
                $ticker['high'],
                $ticker['low'],
                $ticker['number'],
                $ticker['total'],
            ];
        }
    }

    private function huobiKline($symbol, $time, $limit)
    {
        $symbol = strtolower(str_replace('/', '', $symbol));
        $redis = Redis::connection();
        $result = $redis->zrange("huobi:kline:{$symbol}:{$time}", -30, -1);

        return collect($result)->map(function ($item) {
            $item = json_decode($item);

            return [
                'time' => $item[0],
                'open' => (float) $item[1],
                'high' => (float) $item[2],
                'low' => (float) $item[3],
                'close' => (float) $item[4],
                'volume' => (float) $item[5],
                'trades_total' => (float) $item[6],
                'trades_count' => $item[7],
            ];
        })->sortByDesc('time')->values()->all();
    }
}
